{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Table of Contents\n", "* [1. Where are we?](#1.-Where-are-we?)\n", "* [2. LC-3 Input/Output](#2.-LC-3-Input/Output)\n", "\t* [2.1 TRAP Vectors](#2.1-TRAP-Vectors)\n", "\t* [2.2 GETC - Trap x20](#2.2-GETC---Trap-x20)\n", "\t* [2.3 OUT - Trap x21](#2.3-OUT---Trap-x21)\n", "\t* [2.4 PUTS - Trap x22](#2.4-PUTS---Trap-x22)\n", "\t* [2.5 IN - Trap x23](#2.5-IN---Trap-x23)\n", "\t* [2.6 PUTSP - Trap x24](#2.6-PUTSP---Trap-x24)\n", "* [3. Example 9.1](#3.-Example-9.1)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Where are we?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A bit of review, by way of one of our authors:\n", "\n", "The Motivated Bottom-up Approach:\n", "\n", "* https://www.youtube.com/watch?v=dW-M4_o0Ars\n", "\n", "specifically see:\n", "\n", "* https://www.youtube.com/watch?v=dW-M4_o0Ars&feature=youtu.be&t=1588\n", "\n", "Notes:\n", "\n", "* I don't agree with many things he says\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. LC-3 Input/Output" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook explores the TRAP vectors in Input/Output, I/O, in the LC-3." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.1 TRAP Vectors" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "There are a number of TRAP vectors defined by the LC-3 operating system. These" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Trap Vector | Assembly Name | Use\n", "------------|---------------|-----\n", "x20 | GETC | Read a char into R0\n", "x21 | OUT | Write a char in R0 to screen\n", "x22 | PUTS | Write a string (pointer in R0) to screen\n", "x23 | IN | Prompt, read a char into R0, and echo\n", "x24 | PUTSP | Write a PACKED string (pointer in R0) to screen\n", "x25 | HALT | Stop execution\n", "\n", "\n", "\n", "\n", "```\n", " 1. Programmer writes:\n", "```\n", "\n", "```\n", "1111 0000 0010 0011: TRAP x23, or IN\n", "```\n", "\n", "```\n", " 2. Looks in Trap Vector Table, position x23\n", " Saves PC in R7\n", " 3. Gets address of routine, sets PC\n", " 4. Executes routine\n", " 5. Last line of routine is JMP R7, or RET\n", " 6. Execution continues where it left off before trap routine\n", "```\n", "\n", "```\n", "1100 000 111 000000: JMP R7, or RET\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.2 GETC - Trap x20" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Read a char into R0." ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory disassembled:\n", "============================================================\n", " x3000: xF020 GETC [line: 1]\n", " x3001: xF025 HALT [line: 2]\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x3002\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ ".ORIG x3000\n", " TRAP x20\n", " HALT\n", ".END" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "GETC: 1\n", "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 6\n", "Cycles: 54 (0.000027 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 0 Z: 0 P: 1 \n", "R0: x0031 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x3002 \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.3 OUT - Trap x21" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Write a char in R0 to screen" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory disassembled:\n", "============================================================\n", " x3000: x5020 AND R0, R0, #0 [line: 1]\n", " x3001: x1027 ADD R0, R0, #7 [line: 2]\n", " x3002: xF021 OUT [line: 3]\n", " x3003: xF025 HALT [line: 4]\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x3004\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ ".ORIG x3000\n", " AND R0, R0, #0\n", " ADD R0, R0, x07 ;; ASCII A: 65, a: 97\n", " TRAP x21\n", " HALT\n", ".END" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\u0007============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 10\n", "Cycles: 85 (0.000043 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 0 Z: 1 P: 0 \n", "R0: x0007 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x3004 \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.4 PUTS - Trap x22" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Write a string (pointer in R0) to screen" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "PUTS will display a string pointed to by R0, ending in lf (x0A) and \\0 (x00) also called nul.\n", "\n", "A string is a series of characters in memory:\n", "\n", "```\n", "x3003: H\n", "x3004: e\n", "x3005: l\n", "x3006: l\n", "x3007: o\n", "x3008: \\n [linefeed]\n", "x3009: \\0 [nul]\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "But we can't put characters in like that. We must either do this:\n", "\n", "```\n", "x3003: x0048\n", "x3004: x0065 \n", "x3005: x006C \n", "x3006: x006C \n", "x3007: x006F \n", "x3008: x000A\n", "x3009: x0000\n", "```" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory disassembled:\n", "============================================================\n", " x3000: xE002 LEA R0, WORD [line: 1]\n", " x3001: xF022 PUTS [line: 2]\n", " x3002: xF025 HALT [line: 3]\n", "WORD: x3003: x0048 NOOP - (no BR to x304C) (or 72, 'H') [line: 4]\n", " x3004: x0065 NOOP - (no BR to x306A) (or 101, 'e') [line: 5]\n", " x3005: x006C NOOP - (no BR to x3072) (or 108, 'l') [line: 6]\n", " x3006: x006C NOOP - (no BR to x3073) (or 108, 'l') [line: 7]\n", " x3007: x006F NOOP - (no BR to x3077) (or 111, 'o') [line: 8]\n", " x3008: x000A NOOP - (no BR to x3013) (or 10) [line: 9]\n", " x3009: x0000 NOOP - (no BR to x300A) (or 0) [line: 10]\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x300A\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ ".ORIG x3000\n", " LEA R0, WORD\n", " TRAP x22\n", " HALT\n", "WORD: .FILL x0048\n", " .FILL x0065 \n", " .FILL x006C \n", " .FILL x006C \n", " .FILL x006F \n", " .FILL x000A\n", " .FILL x0000\n", ".END" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello\n", "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 79\n", "Cycles: 654 (0.000327 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 0 Z: 0 P: 1 \n", "R0: x3003 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x3003 \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "or do this:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory disassembled:\n", "============================================================\n", " x3000: xE002 LEA R0, WORD [line: 1]\n", " x3001: xF022 PUTS [line: 2]\n", " x3002: xF025 HALT [line: 3]\n", "WORD: x3003: x0048 NOOP - (no BR to x304C) (or 72, 'H') [line: 4]\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x300A\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ ".ORIG x3000\n", " LEA R0, WORD\n", " TRAP x22\n", " HALT\n", "WORD: .STRINGZ \"Hello\\n\"\n", ".END" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory disassembled:\n", "============================================================\n", " x3000: xE002 LEA R0, WORD [line: 1]\n", " x3001: xF022 PUTS [line: 2]\n", " x3002: xF025 HALT [line: 3]\n", "WORD: x3003: x0048 NOOP - (no BR to x304C) (or 72, 'H') [line: 4]\n", " x3004: x0065 - 101 (or 101, 'e')\n", " x3005: x006C - 108 (or 108, 'l')\n", " x3006: x006C - 108 (or 108, 'l')\n", " x3007: x006F - 111 (or 111, 'o')\n", " x3008: x000A - 10 (or 10)\n", " x3009: x0000 - \\0\n" ] } ], "source": [ "%dis x3000 x3009" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello\n", "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 79\n", "Cycles: 654 (0.000327 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 0 Z: 0 P: 1 \n", "R0: x3003 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x3003 \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.5 IN - Trap x23" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Prompt, read a char into R0, and echo" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory disassembled:\n", "============================================================\n", " x3000: xF023 IN [line: 1]\n", " x3001: xF025 HALT [line: 2]\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x3002\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ ".ORIG x3000\n", " TRAP x23\n", " HALT\n", ".END" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Input a character> GETC: 2\n", "2\n", "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 260\n", "Cycles: 2166 (0.001083 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 0 Z: 0 P: 1 \n", "R0: x0032 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x3002 \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 2.6 PUTSP - Trap x24" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The PUTSP is a put-string-packed. Memory contains ASCII letters, two-per word. But note that they are encoded from right to left:\n", "\n", "```\n", " e H\n", " l l\n", " \\0 o\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In hex that would be:\n", "\n", "```\n", "x65 48 \n", "x6c 6c\n", "x00 6f \n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A newline is represented as a LF (line feed), #10, x0A.\n", "\n", "```\n", "x65 48 \n", "x6c 6c\n", "x20 6f \n", "x00 0A\n", "```" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory disassembled:\n", "============================================================\n", " x3000: xE002 LEA R0, WORD [line: 1]\n", " x3001: xF024 PUTSP [line: 2]\n", " x3002: xF025 HALT [line: 3]\n", "WORD: x3003: x6548 LDR R2, R5, 8 [line: 4]\n", " x3004: x6C6C LDR R6, R1, 44 [line: 5]\n", " x3005: x206F LD R0, x3075 [line: 6]\n", " x3006: x000A NOOP - (no BR to x3011) (or 10) [line: 7]\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x3007\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ ".ORIG x3000\n", " LEA R0, WORD\n", " TRAP x24\n", " HALT\n", "WORD: .FILL x6548\n", " .FILL x6c6c\n", " .FILL x206f\n", " .FILL x000A\n", ".END" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Hello \n", "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 303\n", "Cycles: 2041 (0.001020 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 0 Z: 0 P: 1 \n", "R0: x3003 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x3003 \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 3. Example 9.1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Write a game program to do the following: A person is sitting at a keyboard. Each time the person types a capital letter, the program outputs the lowercase version of that latter. If the person types a character \"7\", the program terminates." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "============================================================\n", "Memory disassembled:\n", "============================================================\n", " x3000: x2407 LD R2, TERM [line: 1]\n", " x3001: x2607 LD R3, ASCII [line: 2]\n", "AGAIN: x3002: xF023 IN [line: 3]\n", " x3003: x1280 ADD R1, R2, R0 [line: 4]\n", " x3004: x0405 BRz EXIT (or 5) [line: 5]\n", " x3005: x1003 ADD R0, R0, R3 [line: 6]\n", " x3006: xF021 OUT [line: 7]\n", " x3007: x0FFA BRnzp AGAIN [line: 8]\n", "TERM: x3008: xFFC9 ;; Invalid TRAP vector: x00C9 [line: 9]\n", "ASCII: x3009: x0020 NOOP - (no BR to x302A) (or 32, ' ') [line: 10]\n", "EXIT: x300A: xF025 HALT [line: 11]\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x300B\n", "N: 0 Z: 1 P: 0 \n", "R0: x0000 R1: x0000 R2: x0000 R3: x0000 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x0000 \n" ] } ], "source": [ ".ORIG x3000\n", " LD R2, TERM ;; load negative ASCII 7\n", " LD R3, ASCII ;; load 'a' - 'A' (32)\n", "AGAIN: TRAP x23 ;; Get\n", " ADD R1, R2, R0 \n", " BRz EXIT\n", " ADD R0, R0, R3\n", " TRAP x21\n", " BRnzp AGAIN\n", "TERM: .FILL xFFC9\n", "ASCII: .FILL x0020\n", "EXIT: TRAP x25\n", ".END" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Input a character> GETC: A\n", "A\n", "a\n", "Input a character> GETC: B\n", "B\n", "b\n", "Input a character> GETC: C\n", "C\n", "c\n", "Input a character> GETC: D\n", "D\n", "d\n", "Input a character> GETC: E\n", "E\n", "e\n", "Input a character> GETC: 3\n", "3\n", "S\n", "Input a character> GETC: FEED\n", "F\n", "f\n", "Input a character> E\n", "e\n", "Input a character> E\n", "e\n", "Input a character> D\n", "d\n", "Input a character> GETC: DOUG\n", "D\n", "d\n", "Input a character> O\n", "o\n", "Input a character> U\n", "u\n", "Input a character> G\n", "g\n", "Input a character> GETC: 7\n", "7\n", "============================================================\n", "Computation completed\n", "============================================================\n", "Instructions: 4044\n", "Cycles: 33628 (0.016814 milliseconds)\n", "\n", "============================================================\n", "Registers:\n", "============================================================\n", "PC: x048E\n", "N: 0 Z: 1 P: 0 \n", "R0: x0037 R1: x0000 R2: xFFC9 R3: x0020 \n", "R4: x0000 R5: x0000 R6: x0000 R7: x300B \n" ] } ], "source": [ "%exe" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Calysto LC3", "language": "gas", "name": "calysto_lc3" }, "language_info": { "codemirror_mode": { "name": "gas", "version": 3 }, "file_extension": ".asm", "mimetype": "text/x-gas", "name": "gas" } }, "nbformat": 4, "nbformat_minor": 0 }